home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagg_m.zip / GRAPHICS.SWG / 0064_Sprite Info.pas < prev    next >
Pascal/Delphi Source File  |  1994-01-27  |  3KB  |  92 lines

  1. {
  2. > Another problem is plotting sprites with "invisible" pixels.  In other
  3. > words, all pixels in the sprite are plotted except for ones with a color
  4. > of 255 (I think I've heard that Origin used this method in Ultima 6).
  5. > Because of my unsuccessful try with asm earlier, I didn't even bother to
  6. > try this in asm.  Unfortunately, the following is MUCH too slow:
  7.  
  8. try this!
  9. }
  10. uses crt;
  11. type SpriteType = array[0..15,0..15] of byte;
  12.  
  13. var sprite : spritetype;
  14.     f : file of spritetype;     {sprite's image is stored in file}
  15.     x, y : word;
  16.  
  17. procedure putinvspriteinasm(x, y : word; sprite : spritetype);
  18. var p : pointer;
  19.     segm, offs : word;
  20.     {these are used to calculate destination address
  21.      in video memory}
  22.  
  23. begin
  24.   p := addr(sprite[0,0]);
  25.   {this pointer is used only to cheat tp. tp doesn't allow to use addr or
  26.    @ operators in inline asm - or i don't know how to do it}
  27.   segm := $a000 + (320 * y) div 16;
  28.   offs := x;
  29.   {segm:offs is address of upper left corner of sprite in video RAM}
  30.       asm
  31.           push   ds
  32.   {ds is one of the important registers in tp and must be saved}
  33.           lds    si, p
  34.   {ds:si now is source address for sprite's array}
  35.           mov    es, segm
  36.           mov    di, offs
  37.   {es:di now is target address in VRAM}
  38.           mov    bh, 16
  39.   {counter for outer loop}
  40. @loop2:   mov    bl, 16
  41. @loop1:   mov    al, [ds:si]
  42.   {innner loop (marked with label @loop1) is used to draw each line of
  43.    sprite}
  44.           cmp    al, $ff
  45.    {make sure if pixel is $ff or not}
  46.           je     @skip
  47.    {it is - so we don't draw it}
  48.           mov    [es:di], al
  49.    {no, it's not - draw!}
  50. @skip:    inc    si
  51.           inc    di
  52.           dec    bl
  53.           jnz    @loop1
  54.    {we haven't finished to draw this line if bl > 0}
  55.           dec    bh
  56.    {we haven't finished to draw all image if bh > 0}
  57.           jz     @end
  58.           add    di, 320 - 16
  59.    {calculate beginning of next line}
  60.           jmp    @loop2
  61. @end:
  62.           pop    ds
  63.  
  64.       end
  65. end;
  66.  
  67. begin
  68.   asm mov ax, 0013h
  69.       int 10h
  70.   end;
  71.   assign(f, 'sprite');
  72.   reset(f);
  73.   read(f, sprite);
  74.   close(f);
  75.   randomize;
  76.   repeat
  77.     x := random(320);
  78.     y := random(200);
  79.     putinvspriteinasm(x, y, sprite);
  80.   until keypressed;
  81. end.
  82. {
  83. i added into code some quick'n'dirty comments to let you understand
  84. how assembly works. i've tested this code and found that it won't work with
  85. Microsoft's workgrp.sys driver - the programm simply crashes when you press a
  86. key. (workgrp.sys driver is one of the Windows for Workgroups drivers).
  87. strange... with all other things (qemm386, lan drivers etc.) programm seems to
  88. work fine. one more thing i must add that better is to pass to procedure
  89. putsprite not array with sprite's data but only pointer to it - because tp
  90. moves all this data around memory - and in this case it's 256 bytes.
  91. }
  92.